package mspbots.timedoctor.client.core.client;

import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.log4j.Log4j2;
import mspbots.timedoctor.client.exception.BadRequestException;
import mspbots.timedoctor.client.oauth.V2AuthService;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * data.connector.doctor.client.DoctorV2Client
 *
 * @author Alex bob(https://github.com/vnobo)
 * @date Created by 2020/5/6
 */
@Log4j2
@Service
public class DoctorV2Client extends AbstractClient {

    private final V2AuthService v2AuthService;

    public DoctorV2Client(WebClient.Builder builder, V2AuthService v2AuthService) {
        super(builder.baseUrl("https://api2.timedoctor.com/")
                .defaultHeader("Accept", "application/json").build());
        this.v2AuthService = v2AuthService;
    }

    @Override
    public <T> Mono<T> get(String path, Map<String, Object> params, Class<T> responseType) {
        if (!ObjectUtils.isEmpty(params.get("tenantId"))) {
            Long tenantId = Long.parseLong(params.get("tenantId").toString());
            return this.v2AuthService.getToken(tenantId)
                    .flatMap(token -> this.webClient.get()
                            .uri(uriBuilder -> uriBuilder.path(path).queryParams(ClientUtils.form(params))
                                    .queryParam("token", token).build())
                            .attribute("tenantId", params.get("tenantId"))
                            .accept(MediaType.APPLICATION_JSON)
                            .retrieve()
                            .onStatus(HttpStatus::isError, clientResponse -> clientResponse.bodyToMono(JsonNode.class)
                                    .flatMap(jsonNode -> Mono.error(new BadRequestException(clientResponse.rawStatusCode(), jsonNode.toString()))))
                            .bodyToMono(responseType));
        } else {
            return Mono.error(new BadRequestException(417, "Request-Processing authorization error no [tenantId]"));
        }

    }

}
